/**
 * 在对该项目进行二次开发时，请务必阅读 README.md ，这很有用！
 * https://gitee.com/zjy2100/xgs_wechat
 */

// 全局挂载fetch
import "./utils/fetch.js";
// 全局状态管理
import "./store/index.js";
const {
  hasJwt
} = require("./utils/jwt.js");

// worker线程
let worker;
// 全局事件监听器(用于分发消息)
const messageListeners = new Set();
// 消息队列，worker同一时间仅能干一份工作
const messageQueue = [];

App({

  /**
   * 全局公共变量
   */
  globalData: {},

  /**
   * 注册监听器
   * 务必在页面销毁时调用 unregisterWorkerListener() 方法移除监听器!!!
   * @param {Function} listener 
   */
  registerWorkerListener(listener) {
    messageListeners.add(listener);
  },

  /**
   * 移除监听器
   * 务必在页面销毁时调用该方法移除监听器!!!
   * @param {Function} listener 
   */
  unregisterWorkerListener(listener) {
    messageListeners.delete(listener);
  },

  /**
   * 向worker线程发送消息
   * @param {string} type 类型，woker原样返回
   * @param {object} data 其他数据
   */
  sendMessageToWorker(type, data = {}) {
    if (messageQueue.length === 0) {
      // 消息进队列
      messageQueue.push({
        type,
        data
      });
      worker.postMessage(messageQueue[0]);
    } else {
      // 消息进队列
      messageQueue.push({
        type,
        data
      });
    }
  },

  /**
   * 创建worker线程
   */
  createNewWorker() {
    let that = this;

    worker = wx.createWorker('workers/index.js', {
      useExperimentalWorker: true
    });

    // 监听worker被系统回收事件
    worker.onProcessKilled(() => {
      // 重新创建一个worker
      that.createNewWorker();
    });

    // 监听worker线程发来的消息
    worker.onMessage((res) => {
      if (res.type) {
        // 分发给所有监听器，页面自行判断自己的消息
        messageListeners.forEach(listener => listener(res));
      }
      // 出队第一个
      messageQueue.shift();
      if (messageQueue.length > 0) {
        worker.postMessage(messageQueue[0]);
      }
    });
  },

  /**
   * 当小程序初始化完成时，会触发 onLaunch（全局只触发一次）
   */
  onLaunch: function () {
    // 创建worker线程，全局仅能创建一个
    this.createNewWorker();
  },

  /**
   * 当小程序启动，或从后台进入前台显示，会触发 onShow
   */
  onShow: function (options) {
    hasJwt();
  },

  /**
   * 当小程序从前台进入后台，会触发 onHide
   */
  onHide: function () {

  },

  /**
   * 当小程序发生脚本错误，或者 api 调用失败时，会触发 onError 并带上错误信息
   */
  onError: function (msg) {

  }
})